package com.baiduspring.service.specialcolumn.impl;

import com.baiduspring.error.BaiduSpringException;
import com.baiduspring.function.elasticsearch.ElasticsearchHandle;
import com.baiduspring.function.elasticsearch.error.ElasticSearchException;
import com.baiduspring.function.elasticsearch.operation.Doc;
import com.baiduspring.function.elasticsearch.operation.QueryInput;
import com.baiduspring.function.elasticsearch.operation.QueryResultsOutput;
import com.baiduspring.service.specialcolumn.BlogService;
import com.baiduspring.service.specialcolumn.SpecialColumnIndexEnum;
import com.baiduspring.service.user.UserService;
import com.baiduspring.utils.enums.ValidStatusEnum;
import com.baiduspring.utils.string.StringUtils;
import com.baiduspring.vo.BlogVO;
import com.baiduspring.vo.ResultsVO;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.index.IndexNotFoundException;
import org.elasticsearch.index.query.QueryBuilder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.Optional;

@Service
@Slf4j
public class BlogServiceImpl implements BlogService {
    @Resource
    private UserService userService;

    @Override
    public void create(BlogVO blogVO) {
        //生成唯一的id值
        String id = StringUtils.uuid();
        long timestamp = System.currentTimeMillis();

        Doc<String, Object> doc = new Doc<>();
        doc.field("title", blogVO.getTitle());
        doc.field("orig", blogVO.getOrig());
        doc.field("columnChannel", blogVO.getChannels());
        doc.field("label", blogVO.getLabel());
        doc.field("content", blogVO.getContent());
        doc.field("contentTxt", blogVO.getContentTxt());
        doc.field("authorAccount", blogVO.getAccount());
        doc.field("status", ValidStatusEnum.ENABLE.toString());
        doc.field("readNum", 0);
        doc.field("collectNum", 0);
        doc.field("likesNum", 0);
        doc.field("uriMark", timestamp);
        doc.field("ip", blogVO.getIp());
        doc.field("createDate", timestamp);
        doc.field("updateDate", timestamp);
        try {
            ElasticsearchHandle.instance().indexDocs(
                    SpecialColumnIndexEnum.SPECIAL_COLUMN_BLOG_INDEX.getValue(),
                    SpecialColumnIndexEnum.SPECIAL_COLUMN_BLOG_TYPE.getValue(),
                    id, Mapping.MAPPING_JSON_FILE_PATH, doc);
        } catch (ElasticSearchException e) {
            log.error("槽糕，发布失败！错误：{}", e);
            throw e;
        }
    }

    @Override
    public Optional<QueryResultsOutput> queryAndPagging(QueryInput input) {
        String[] indies = {SpecialColumnIndexEnum.SPECIAL_COLUMN_BLOG_INDEX.getValue()};
        String[] types = {SpecialColumnIndexEnum.SPECIAL_COLUMN_BLOG_TYPE.getValue()};

        Map<String, Class> outputFields = Maps.newHashMap();
        outputFields.put("title", String.class);
        outputFields.put("orig", Integer.class);
        outputFields.put("columnChannel", Integer.class);
        outputFields.put("label", String.class);
        outputFields.put("content", String.class);
        outputFields.put("contentTxt", String.class);
        outputFields.put("authorAccount", Long.class);
        outputFields.put("status", String.class);
        outputFields.put("readNum", Integer.class);
        outputFields.put("collectNum", Integer.class);
        outputFields.put("likesNum", Integer.class);
        outputFields.put("uriMark", Long.class);
        outputFields.put("ip", String.class);
        outputFields.put("createDate", Long.class);
        outputFields.put("updateDate", Long.class);

        input.setIndices(indies);
        input.setTypes(types);
        input.setOutputFields(outputFields);

        StringBuilder builder = new StringBuilder();
        List<ResultsVO> list = Lists.newArrayList();
        Optional<QueryResultsOutput> optional;
        try {
            optional = ElasticsearchHandle.instance().search(input, true, ResultsVO.class);
        } catch (IndexNotFoundException e) {
            log.error("数据检索错误：{}", e);
            throw new BaiduSpringException("数据检索错误：no such index");
        }

//        optional.ifPresent(resultsOutput -> resultsOutput.getResults().forEach(o -> {
//            ResultsVO vo = (ResultsVO) o;
//
//            HanLP.extractSummary(vo.getContentTxt(), 3).forEach(s -> builder.append(s).append("，"));
//            builder.deleteCharAt(builder.lastIndexOf("，"));
//            vo.setSummary(builder.toString());
//
//            builder.delete(0, builder.length());
//
//            userService.getByAccount(vo.getAuthorAccount()).ifPresent(user -> vo.setUser(user));
//
//            list.add(vo);
//        }));

        return optional;
    }

    @Override
    public Optional<QueryResultsOutput> queryMultipleConditions(QueryBuilder queryBuilder) {
        String[] indies = {SpecialColumnIndexEnum.SPECIAL_COLUMN_BLOG_INDEX.getValue()};
        String[] types = {SpecialColumnIndexEnum.SPECIAL_COLUMN_BLOG_TYPE.getValue()};

        Map<String, Class> outputFields = Maps.newHashMap();
        outputFields.put("title", String.class);
        outputFields.put("orig", Integer.class);
        outputFields.put("label", String.class);
        outputFields.put("content", String.class);
        outputFields.put("authorAccount", Long.class);
        outputFields.put("readNum", Integer.class);
        outputFields.put("collectNum", Integer.class);
        outputFields.put("likesNum", Integer.class);

        QueryInput input = new QueryInput();
        input.setIndices(indies);
        input.setTypes(types);
        input.setOutputFields(outputFields);

        Optional<QueryResultsOutput> outputOptional = ElasticsearchHandle.instance().searchMultipleConditions(input, queryBuilder, ResultsVO.class);

        outputOptional.ifPresent(output -> output.getResults().forEach(o -> {
            ResultsVO vo = (ResultsVO) o;
            userService.getByAccount(vo.getAuthorAccount()).ifPresent(user -> vo.setUser(user));
        }));

        return outputOptional;
    }

    private class Mapping {
        private static final String MAPPING_JSON_FILE_PATH = "config/es/specialcolumn_blog.json";
    }
}
